// ignore_for_file: constant_identifier_names

import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:crypto/crypto.dart';

import 'package:flutter/foundation.dart';
import 'package:hockey/jzx_apps.dart';
import 'package:hockey/services/jzx_app.dart';
import 'package:hockey/services/jzx_user.dart';

/// 打点中所有涉及到的页面KEY
enum JzxLogPages {
  home_tab,
  video_tab,
  post_tab,
  mine_tab,

  // 登录页面埋点
  /// 1. 启动页面埋点，page -- ’launch‘
  launch,

  ///  1. 快速登录，page -- 'quicklogin'
  quicklogin,

  /// 2. 苹果登录，page -- 'applelogin'
  applelogin,

  /// 3. 用户协议，page -- 'terms'
  terms,

  /// 4. 隐私协议，page -- 'privacy'
  privacy,

  /// 5. 登录成功 ，page -- 'loginsuccess'
  loginsuccess,

  // 内购埋点
  /// 1. 打开充值页面，page -- 'purchase'
  purchase,

  /// 2. 创建内购订单，page -- 'createorder'
  createorder,

  // 我的埋点
  ///   1. 编辑头像，page -- 'editavatar'
  editavatar,

  ///   2. 退出登录，page -- 'logout'
  logout,

  ///   3. 删除账号，page -- 'deleteaccount'
  deleteaccount,

  ///   4. 点击客服，page -- 'customer'
  customer,

  // 其它
  /// 1. 举报，page -- 'report'
  report,

  /// 2. 拉黑，page -- 'block'
  block;
}

class JzxLogPvManger {
  JzxLogPvManger._();

  static const String _event = 'event';
  static const String _tm = 'tm';
  static const String _page = 'page';
  static const String _subPage = 'subPage';
  static const String _terPage = 'terPage';
  static const String _broadcasterId = 'broadcasterId';
  static const String _duration = 'duration';

  static void tracking({
    JzxLogPages? page,
    String? subPage,
    String? terPage,
    String? broadcasterId,
  }) {
    var map = <String, dynamic>{};
    // ⚠️page传入下方的埋点事件page值
    if (page != null) {
      map[_page] = page.name;
    }
    if (subPage != null) {
      map[_subPage] = subPage;
    }
    if (terPage != null) {
      map[_terPage] = terPage;
    }
    if (broadcasterId != null) {
      map[_broadcasterId] = broadcasterId;
    }
    map[_duration] = 0;
    map[_event] = 'pv';
    map[_tm] = DateTime.now().millisecondsSinceEpoch;

    if (kDebugMode) {
      log('$map', name: 'LogPvMgr');
    }
    JzxLogManger().submitLog(JzxLogType.globalBehavior, map);
  }
}

/// 打点类型
enum JzxLogType {
  globalBehavior('event', 'global_behavior', 'event'),
  clickEvent("event", "click", "event");

  final String logType;
  final String subType;
  final String behavior;

  const JzxLogType(this.logType, this.subType, this.behavior);
}

///使用md5加密
String generateMD5(String data) {
  Uint8List content = const Utf8Encoder().convert(data);
  Digest digest = md5.convert(content);
  return digest.toString();
}

// 打点管理
class JzxLogManger {
  static final JzxLogManger _instance = JzxLogManger._internal();
  factory JzxLogManger() {
    return _instance;
  }
  JzxLogManger._internal();

  static const String tag = "JzxLogManger"; // 日志标签
  static const int limitSize = 20; // 打点任务最多缓存长度
  static int _serialId = 0;

  // 每次启动App该值会修改
  static String launcherId = generateMD5(
      '${DateTime.now().millisecondsSinceEpoch}${JzxAppService.to.device.identifier}');

  final List<Map<String, dynamic>> cacheList = [];
  bool _isWaitingForSend = false; // 是否需要延迟上报

  /// 上报日志
  void submitLog(JzxLogType logType, Map<String, dynamic>? event) {
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    cacheList.insert(0, itemData);
    _ploymentDelayed();
  }

  /// 延时发送日志
  void _ploymentDelayed() {
    if (_isWaitingForSend) {
      return;
    }
    _isWaitingForSend = true;
    Timer(const Duration(milliseconds: 2000), () {
      _isWaitingForSend = false;
      _ploymentLog(false);
    });
  }

  /// 发日志打点
  void _ploymentLog(bool forceUploadAll) {
    try {
      List<Map<String, dynamic>> sendList = [];
      if (cacheList.isEmpty) {
        return;
      } else if (cacheList.length >= limitSize && !forceUploadAll) {
        sendList.addAll(cacheList.sublist(0, limitSize));
        cacheList.removeRange(0, limitSize);
      } else {
        sendList.addAll(cacheList);
        cacheList.clear();
      }
      _startUpload(sendList, true);
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
    }
  }

  /// 立马发送日志
  void submitLogRightNow(JzxLogType logType, Map<String, dynamic>? event) {
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    List<Map<String, dynamic>> list = [];
    list.add(itemData);

    _startUpload(list, false);
  }

  /// 执行上传
  Future<void> _startUpload(
      List<Map<String, dynamic>> sendList, bool isContinue) async {
    // 提交
    JzxNetRepository.bpClient.eventTracking(sendList).then((value) {
      if (isContinue) {
        _ploymentDelayed();
      }
    });

    // Dio()
    //     .post(appDomain.bpHost + kApiEventTracking, data: sendList)
    //     .then((value) {
    //   if (isContinue) {
    //     _ploymentDelayed();
    //   }
    // });
  }

  Map<String, dynamic> _buildItemData(String logType, String subType,
      String behavior, Map<String, dynamic>? event) {
    String platform = '';
    String model = '';
    if (Platform.isAndroid) {
      platform = 'Android';
      model = JzxAppService.to.device.model;
    } else if (Platform.isIOS) {
      platform = 'iOS';
      model = JzxAppService.to.device.model;
    }
    Map<String, dynamic> itemData = {};
    itemData[JzxLogHeadersKey.jzxData] = [event];
    itemData[JzxLogHeadersKey.jzxLogType] = 'event';
    itemData[JzxLogHeadersKey.jzxSubtype] = 'global_behavior';
    itemData[JzxLogHeadersKey.jzxBehavior] = 'event';
    itemData[JzxLogHeadersKey.jzxDeviceId] = JzxAppService.to.device.identifier;
    itemData[JzxLogHeadersKey.jzxUserId] = JzxUserService.to.uid;
    itemData[JzxLogHeadersKey.jzxPkg] =
        JzxAppService.to.packageInfo?.packageName;
    itemData[JzxLogHeadersKey.jzxChnId] = '';
    itemData[JzxLogHeadersKey.jzxVer] = JzxAppService.to.packageInfo?.version;
    itemData[JzxLogHeadersKey.jzxPlatform] = platform;
    itemData[JzxLogHeadersKey.jzxModel] = model;
    itemData[JzxLogHeadersKey.jzxPVer] =
        JzxAppService.to.packageInfo?.buildNumber;
    itemData[JzxLogHeadersKey.jzxLanId] = launcherId;
    itemData[JzxLogHeadersKey.jzxSecId] = _serialId++;
    itemData[JzxLogHeadersKey.jzxsysLan] = Get.locale?.languageCode;
    itemData[JzxLogHeadersKey.jzxCountry] = Get.locale?.languageCode;
    itemData["tm"] = DateTime.now().millisecondsSinceEpoch;
    return itemData;
  }
}

/// 打点请求头key统一传参
class JzxLogHeadersKey {
  static const String jzxData = "data";
  static const String jzxLogType = "log_type";
  static const String jzxSubtype = "subtype";
  static const String jzxBehavior = "behavior";
  static const String jzxDeviceId = "device-id";
  static const String jzxAndroidId = "android_id";
  static const String jzxUserId = "user_id";
  static const String jzxPkg = "pkg";
  static const String jzxChnId = "chn_id";
  static const String jzxVer = "ver";
  static const String jzxPlatform = "platform";
  static const String jzxModel = "model";
  static const String jzxPVer = "p_ver";
  static const String jzxLanId = "lan_id";
  static const String jzxSecId = "sec_id";
  static const String jzxUtmSource = "utm_source";
  static const String jzxAfAdgroupId = "af_adgroup_id";
  static const String jzxAfAdset = "af_adset";
  static const String jzxAfAdsetId = "af_adset_id";
  static const String jzxAfStatus = "af_status";
  static const String jzxAfAgency = "af_agency";
  static const String jzxAfChannel = "af_channel";
  static const String jzxAfCampaign = "campaign";
  static const String jzxAfCampaignId = "campaign_id";
  static const String jzxCountry = "country";
  static const String jzxsysLan = "sys_lan";
}
